From 04913aea58a152ebc482abbb1d9c94a21349faeb Mon Sep 17 00:00:00 2001 From: oliskoli Date: Sat, 22 Jul 2006 22:38:57 +0000 Subject: [PATCH] Check in new common GPSBabel file I/O api 'gbfile'. Please don't use 'textfile' anymore. It'll replaced with gbfile. git-svn-id: http://gpsbabel.googlecode.com/svn/trunk@2256 f51c46e8-681c-474f-0cfe-069cfd0219fb --- gpsbabel/Makefile.in | 26 ++- gpsbabel/defs.h | 2 + gpsbabel/gbfile.c | 514 +++++++++++++++++++++++++++++++++++++++++++ gpsbabel/gbfile.h | 86 ++++++++ gpsbabel/gbtypes.h | 2 + gpsbabel/palmdoc.c | 4 +- 6 files changed, 631 insertions(+), 3 deletions(-) create mode 100644 gpsbabel/gbfile.c create mode 100644 gpsbabel/gbfile.h diff --git a/gpsbabel/Makefile.in b/gpsbabel/Makefile.in index a031c7f06..5f0959bbf 100644 --- a/gpsbabel/Makefile.in +++ b/gpsbabel/Makefile.in @@ -70,11 +70,16 @@ COLDSYNC=coldsync/util.o coldsync/pdb.o SHAPE=shapelib/shpopen.o shapelib/dbfopen.o +ZLIB=zlib/adler32.o zlib/compress.o zlib/crc32.o zlib/deflate.o zlib/inffast.o \ + zlib/inflate.o zlib/infback.o zlib/inftrees.o zlib/trees.o \ + zlib/uncompr.o zlib/gzio.o zlib/zutil.o + LIBOBJS = queue.o route.o waypt.o filter_vecs.o util.o vecs.o mkshort.o \ csv_util.o strptime.o grtcirc.o vmem.o util_crc.o xmlgeneric.o \ uuid.o formspec.o xmltag.o cet.o cet_util.o fatal.o rgbcolors.o \ inifile.o garmin_fs.o gbsleep.o units.o textfile.o @GBSER@ gbser.o \ - $(COLDSYNC) $(GARMIN) $(JEEPS) $(SHAPE) $(FMTS) $(FILTERS) + gbfile.o \ + $(COLDSYNC) $(GARMIN) $(JEEPS) $(SHAPE) $(ZLIB) $(FMTS) $(FILTERS) OBJS = main.o globals.o $(LIBOBJS) .c.o: @@ -320,6 +325,9 @@ garmin_txt.o: garmin_txt.c defs.h config.h queue.h gbtypes.h cet.h \ jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h garmin_tables.h \ grtcirc.h jeeps/gpsmath.h strptime.h +gbfile.o: gbfile.h gbfile.c config.h defs.h gbtypes.h \ + zlib/crc32.h zlib/deflate.h zlib/inffast.h zlib/inffixed.h zlib/inflate.h \ + zlib/inftrees.h zlib/trees.h zlib/zconf.h zlib/zlib.h zlib/zutil.h gbsleep.o: gbsleep.c config.h gcdb.o: gcdb.c defs.h config.h queue.h gbtypes.h cet.h cet_util.h \ inifile.h coldsync/palm.h coldsync/../gbtypes.h coldsync/pdb.h @@ -661,5 +669,21 @@ jeeps/gpsutil.o: jeeps/gpsutil.c jeeps/gps.h jeeps/../defs.h \ jeeps/gpsproj.h shapelib/dbfopen.o: shapelib/dbfopen.c shapelib/shapefil.h shapelib/shpopen.o: shapelib/shpopen.c shapelib/shapefil.h +zlib/adler32.o: zlib/zlib.h zlib/zconf.h +zlib/compress.o: zlib/zlib.h zlib/zconf.h +zlib/crc32.o: zlib/crc32.h zlib/zlib.h zlib/zconf.h +zlib/deflate.o: zlib/deflate.h zlib/zutil.h zlib/zlib.h zlib/zconf.h +zlib/gzio.o: zlib/gzio.c zlib/zutil.h zlib/zlib.h zlib/zconf.h +zlib/inffast.o: zlib/zutil.h zlib/zlib.h zlib/zconf.h zlib/inftrees.h \ + zlib/inflate.h zlib/inffast.h +zlib/inflate.o: zlib/zutil.h zlib/zlib.h zlib/zconf.h zlib/inftrees.h \ + zlib/inflate.h zlib/inffast.h +zlib/infback.o: zlib/zutil.h zlib/zlib.h zlib/zconf.h zlib/inftrees.h \ + zlib/inflate.h zlib/inffast.h +zlib/inftrees.o: zlib/zutil.h zlib/zlib.h zlib/zconf.h zlib/inftrees.h +zlib/trees.o: zlib/deflate.h zlib/zutil.h zlib/zlib.h zlib/zconf.h \ + zlib/trees.h +zlib/uncompr.o: zlib/zlib.h zlib/zconf.h +zlib/zutil.o: zlib/zutil.h zlib/zlib.h zlib/zconf.h internal_styles.c: mkstyle.sh style/arc.style style/cambridge.style style/csv.style style/cup.style style/custom.style style/dna.style style/fugawi.style style/garmin301.style style/garmin_poi.style style/geonet.style style/gpsdrive.style style/gpsdrivetrack.style style/gpsman.style style/ktf2.style style/kwf2.style style/mapconverter.style style/mxf.style style/nima.style style/openoffice.style style/s_and_t.style style/saplus.style style/tabsep.style style/xmap2006.style style/xmap.style style/xmapwpt.style style/sportsim.style ./mkstyle.sh > internal_styles.c || (rm -f internal_styles.c ; exit 1) diff --git a/gpsbabel/defs.h b/gpsbabel/defs.h index e6c71491e..bae98af0f 100644 --- a/gpsbabel/defs.h +++ b/gpsbabel/defs.h @@ -28,6 +28,8 @@ #include "config.h" #include "queue.h" #include "gbtypes.h" +#include "zlib/zlib.h" +#include "gbfile.h" #include "cet.h" #include "cet_util.h" #include "inifile.h" diff --git a/gpsbabel/gbfile.c b/gpsbabel/gbfile.c new file mode 100644 index 000000000..37ac063b6 --- /dev/null +++ b/gpsbabel/gbfile.c @@ -0,0 +1,514 @@ +/* + + Common GPSBabel file I/O API + + Copyright (C) 2006 Olaf Klein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "gbfile.h" + +#include +#include +#include +#include +#include + +#define MYNAME "gdbfile" + +gbfile * +gbfopen(const char *filename, const char *mode, const char *module) +{ + gbfile *file; + const char *m; + int len; + + file = xcalloc(1, sizeof(*file)); + + file->name = xstrdup(filename); + file->module = xstrdup(module); + file->line = xstrdup(""); + file->mode = 'r'; // default + file->binary = (strchr(mode, 'b') != NULL); + + for (m = mode; *m; m++) { + switch(tolower(*m)) { + case 'r': + file->mode = 'r'; + file->gzapi = 1; + break; + case 'w': + file->mode = 'w'; + break; + } + } + + /* Do we have a '.gz' extension in the filename ? */ + len = strlen(file->name); + if ((len > 3) && (case_ignore_strcmp(&file->name[len-3], ".gz") == 0)) { + /* force gzipped files on output */ + file->gzapi = 1; + } + + if (file->gzapi) { + file->f = gzopen(filename, mode); + if (file->f == NULL) { + fatal("%s: Cannot %s file '%s'!\n", + module, + (file->mode == 'r') ? "open" : "create", + filename); + } + file->gzapi = 1; + } + else { + file->f = xfopen(filename, mode, module); + } + + return file; +} + +/* + * gbfopen_be: as gbfopen, but set the BIG-ENDIAN flag + */ + +gbfile * +gbfopen_be(const char *filename, const char *mode, const char *module) +{ + gbfile *result; + + result = gbfopen(filename, mode, module); + result->big_endian = 1; + + return result; +} + +void +gbfclose(gbfile *file) +{ + if (!file) return; + + if (file->gzapi) { + gzclose( (gzFile *) file->f); + } + else { + fclose( (FILE *) file->f); + } + xfree(file->name); + xfree(file->module); + xfree(file->line); + xfree(file); +} + +int +gbfgetc(gbfile *file) +{ + unsigned char c; + + /* errors are catched in gbfread */ + if (gbfread(&c, 1, 1, file) == 0) { + return EOF; + } + else { + return (unsigned int)c; + } +} + +char * +gbfgets(gbfile *file, char *buf, int len) +{ + if (file->gzapi) { + return gzgets( (gzFile *) file->f, buf, len); + } + else { + return fgets(buf, len, (FILE *) file->f); + } +} + + +gbsize_t +gbfread(void *buf, const gbsize_t size, const gbsize_t members, gbfile *file) +{ + if ((size == 0) || (members == 0)) return 0; + + if (file->gzapi) { + int result = gzread( (gzFile *) file->f, buf, size * members) / size; + if ((result < 0) || ((gbsize_t)result < members)) { + int errnum; + const char *errtxt; + + errtxt = gzerror( (gzFile *) file->f, &errnum); + if ((errnum != Z_STREAM_END) && (errnum != 0)) + fatal("%s: zlib returned error %d ('%s')!\n", + file->module, errnum, errtxt); + } + return (gbsize_t) result; + } + else { + int errno; + gbsize_t result = fread(buf, size, members, (FILE *) file->f); + + if ((result < members) && (errno = ferror( (FILE *) file->f))) { + fatal("%s: Error %d occured during read of file '%s'!\n", + file->module, errno, file->name); + } + return result; + } +} + +int +gbfprintf(gbfile *file, const char *format, ...) +{ + int len, result; + char *buf; + va_list args; + char tmp[256]; /* probably enough for 99.9 percent of our code */ + + va_start(args, format); + len = vsnprintf(tmp, sizeof(tmp), format, args); + va_end(args); + + if (len < sizeof(tmp)) buf = tmp; + else { + buf = xmalloc(len + 1); + + va_start(args, format); + vsnprintf(buf, len + 1, format, args); + va_end(args); + } + result = gbfwrite(buf, 1, len, file); + if (buf != tmp) xfree(buf); + + return result; +} + +int +gbfputc(int c, gbfile *file) +{ + unsigned char temp = (unsigned int) c; + + gbfwrite(&temp, 1, 1, file); + + return c; +} + +int +gbfputs(const char *s, gbfile *file) +{ + return gbfwrite(s, 1, strlen(s), file); +} + +int +gbfwrite(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *file) +{ + int result; + + if ((size == 0) || (members == 0)) return 0; + + if (file->gzapi) { + result = gzwrite( (gzFile *) file->f, buf, size * members) / size; + } + else { + result = fwrite(buf, size, members, (FILE *) file->f); + } + + if (result != members) { + fatal("%s: Could not write %u bytes to %s!\n", + file->module, + (members - result) * size, + file->name); + } + + return result; +} + +int +gbfflush(gbfile *file) +{ + if (file->gzapi) { + return gzflush( (gzFile *) file->f, Z_SYNC_FLUSH); + } + else { + return fflush( (FILE *) file->f); + } +} + +void +gbfclearerr(gbfile *file) +{ + if (file->gzapi) { + gzclearerr( (gzFile *) file->f); + } + else { + clearerr( (FILE *) file->f); + } +} + +int +gbferror(gbfile *file) +{ + int errnum; + + if (file->gzapi) { + (void)gzerror( (gzFile *) file->f, &errnum); + } + else { + errnum = ferror( (FILE *) file->f); + } + return errnum; +} + +void +gbfrewind(gbfile *file) +{ + if (file->gzapi) { + gzrewind( (gzFile *) file->f); + } + else { + rewind( (FILE *) file->f); + } +} + +int +gbfseek(gbfile *file, gbsize_t offset, int whence) +{ + int result; + + if (file->gzapi) { + assert(whence != SEEK_END); + result = gzseek( (gzFile *) file->f, offset, whence); + is_fatal(result < 0, + "%s: online compression not yet supported for this format!", file->module); + return 0; + + } + else { + return fseek( (FILE *) file->f, offset, whence); + } +} + +gbsize_t +gbftell(gbfile *file) +{ + if (file->gzapi) { + return gztell( (gzFile *) file->f); + } + else { + return ftell( (FILE *) file->f); + } +} + +int +gbfeof(gbfile *file) +{ + if (file->gzapi) { + return gzeof( (gzFile *) file->f); + } + else { + return feof( (FILE *) file->f); + } +} + +int +gbfungetc(const int c, gbfile *file) +{ + if (file->gzapi) { + return gzungetc(c, (gzFile *) file->f); + } + else { + return ungetc(c, (FILE *) file->f); + } +} + +/* ----------------------------------------------------------- */ + +gbint32 +gbfgetint32(gbfile *file) +{ + char buf[4]; + + gbfread(buf, 1, sizeof(buf), file); + + if (file->big_endian) + return be_read32(buf); + else + return le_read32(buf); +} + +gbint16 +gbfgetint16(gbfile *file) +{ + char buf[2]; + + gbfread(buf, 1, sizeof(buf), file); + + if (file->big_endian) + return be_read16(buf); + else + return le_read16(buf); +} + +double +gbfgetdbl(gbfile *file) +{ + char buf[8]; + double result; + + gbfread(buf, 1, sizeof(buf), file); + le_read64(&result, buf); + + return result; +} + +/* + * gbfgetcstr: Reads a string from file until either a '\0' or eof. + * The result is a temporary allocated entity: use it or free it! + */ +char * +gbfgetcstr(gbfile *file) +{ + int len, size; + char *result; + + len = size = 0; + result = xstrdup(""); + + while (1) { + char c = gbfgetc(file); + + if ((c == 0) || (c == EOF)) break; + + if (len == size) { + size += 32; + result = xrealloc(result, size + 1); + } + result[len] = c; + len++; + } + + if ((len + 1) != size) + result = xrealloc(result, len + 1); + + return result; +} + +/* + * gbfgetstr: Reads a pascal string (first byte is length) from file. + * The result is a temporary allocated entity: use it or free it! + */ +char * +gbfgetpstr(gbfile *file) +{ + int len; + char *result; + + len = gbfgetc(file); + result = xmalloc(len + 1); + + if (len > 0) + gbfread(result, 1, len, file); + result[len] = '\0'; + + return result; +} + +/* + * gbfgetstr: read a string from file (util any type of line-breaks or eof or error) + * except free you can do all possible things with the result + */ +char * +gbfgetstr(gbfile *file) +{ + int len; + char *result = file->line; + + len = file->lsize = 0; + + while (1) { + char c = gbfgetc(file); + + if ((c == EOF) || (c == 0x1A)) { + if (len == 0) { + return NULL; + } + break; + } + else if (c == '\r') { + c = gbfgetc(file); + if ((c != '\n') && (c != EOF)) gbfungetc(c, file); + break; + } + else if (c == '\n') { + break; + } + if (len == file->lsize) { + file->lsize = len + 128; + result = file->line = xrealloc(file->line, len + 128 + 1); + } + result[len] = c; + len++; + } + result[len] = '\0'; // terminate resulting string + + return result; +} + +int +gbfputint16(const gbint16 i, gbfile *file) +{ + char buf[2]; + + if (file->big_endian) + be_write16(buf, i); + else + le_write16(buf, i); + return gbfwrite(buf, 1, sizeof(buf), file); +} + +int +gbfputint32(const gbint32 i, gbfile *file) +{ + char buf[4]; + + if (file->big_endian) + be_write32(buf, i); + else + le_write32(buf, i); + return gbfwrite(buf, 1, sizeof(buf), file); +} + +int +gbfputdbl(const double d, gbfile *file) +{ + char buf[8]; + + le_read64(buf, (char *)&d); + return gbfwrite(buf, 1, sizeof(buf), file); +} + +int +gbfputpstr(const char *s, gbfile *file) +{ + int len; + + len = strlen(s); + if (len > 255) len = 255; + gbfputc(len, file); + gbfwrite(s, 1, len, file); + + return len + 1; +} diff --git a/gpsbabel/gbfile.h b/gpsbabel/gbfile.h new file mode 100644 index 000000000..81934526d --- /dev/null +++ b/gpsbabel/gbfile.h @@ -0,0 +1,86 @@ +/* + + Common GPSBabel file I/O API + + Copyright (C) 2006 Olaf Klein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#ifndef GBFILE_H +#define GBFILE_H + +#include "config.h" +#include "defs.h" +#include "zlib/zlib.h" +#include + + +typedef struct gbfile_s { +#ifdef DEBUG_MEM + void *dummy; /* ZERO pointer for stdio oop's */ +#endif + void *f; + char *name; + char *module; + char *line; + int lsize; + char mode; + unsigned char big_endian:1; + unsigned char binary:1; + unsigned char gzapi:1; +} gbfile; + + +gbfile *gbfopen(const char *filename, const char *mode, const char *module); +gbfile *gbfopen_be(const char *filename, const char *mode, const char *module); +#define gbfopen_le gbfopen +void gbfclose(gbfile *file); + +gbsize_t gbfread(void *buf, const gbsize_t size, const gbsize_t members, gbfile *file); +int gbfgetc(gbfile *file); +char *gbfgets(gbfile *file, char *buf, int len); + +int gbfprintf(gbfile *file, const char *format, ...); +int gbfputc(int c, gbfile *file); +int gbfputs(const char *s, gbfile *file); +int gbfwrite(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *file); +int gbfflush(gbfile *file); + +void gbfclearerr(gbfile *file); +int gbferror(gbfile *file); +void gbfrewind(gbfile *file); +int gbfseek(gbfile *file, gbsize_t offset, int whence); +gbsize_t gbftell(gbfile *file); +int gbfeof(gbfile *file); +int gbfungetc(const int c, gbfile *file); + +gbint32 gbfgetint32(gbfile *file); +#define gbfgetuint32(a) (gbuint32)gbfgetint32((a)) +gbint16 gbfgetint16(gbfile *file); +#define gbfgetuint16(a) (gbuint16)gbfgetint16((a)) +double gbfgetdbl(gbfile *file); // read double value +char *gbfgetstr(gbfile *file); // read until any type of line-breaks of EOF +char *gbfgetpstr(gbfile *file); // read a pascal string + +int gbfputint16(const gbint16 i, gbfile *file); +#define gbfputuint16 gbfputint16((gbuint16)(a),(b)) +int gbfputint32(const gbint32 i, gbfile *file); +#define gbfputuint32(a,b) gbfputint16((gbuint32)(a),(b)) +int gbfputdbl(const double d, gbfile *file); // write double value +int gbfputpstr(const char *s, gbfile *file); // write as pascal string + +#endif diff --git a/gpsbabel/gbtypes.h b/gpsbabel/gbtypes.h index 1cde76609..ad16fc88a 100644 --- a/gpsbabel/gbtypes.h +++ b/gpsbabel/gbtypes.h @@ -51,4 +51,6 @@ typedef int16_t gbint16; #endif /* defined(_MSC_VER) */ +typedef gbuint32 gbsize_t; + #endif /* gb_types_h_included */ diff --git a/gpsbabel/palmdoc.c b/gpsbabel/palmdoc.c index ab69d2628..f20d77619 100644 --- a/gpsbabel/palmdoc.c +++ b/gpsbabel/palmdoc.c @@ -143,7 +143,7 @@ static unsigned char * mem_find(unsigned char *t, int t_len, unsigned char *m, i } -static void compress( struct buffer *b ) +static void pd_compress( struct buffer *b ) { unsigned i, j; @@ -316,7 +316,7 @@ static void commit_buffer( void ) { newrec->size = buf.len; recordsize_tail = newrec; - compress( &buf ); + pd_compress( &buf ); opdb_rec = new_Record (0, 0, ct++, (uword) buf.len, (const ubyte *)buf.data); -- 2.30.2